classdef RequirementFilterManager
    % RequirementFilterManager - 需求过滤器管理工具类
    %
    % 功能：
    % - 从配置文件读取过滤器定义
    % - 动态创建GUI过滤器面板
    % - 构建过滤器结构体供数据过滤使用
    %
    % 设计原则：
    % - 遵循DO-178规则第4条：业务逻辑与GUI分离
    % - 遵循DO-178规则第2条：不硬编码过滤器定义，从配置文件读取
    % - 纯静态方法，无状态，便于测试
    %
    % 使用示例：
    %   % 读取过滤器配置
    %   filterConfig = RequirementFilterManager.loadFilterConfig(configPath);
    %  
    %   % 创建过滤器面板
    %   [filterPanel, filterControls] = RequirementFilterManager.createFilterPanel(...
    %       parentGrid, row, reqType, filterConfig, attributeConfig);
    %
    %   % 构建过滤器结构体
    %   filters = RequirementFilterManager.buildFilterStruct(filterControls);
    %
    % 作者：DO-178项目开发团队
    % 日期：2025-10-19
    % 版本：1.0
    
    methods (Static)
        
        function [filterConfig, attributeConfig] = loadFilterConfig(configPath)
            % 加载过滤器配置
            % 输入：configPath - 配置文件路径
            % 输出：
            %   filterConfig - 过滤器配置结构体
            %   attributeConfig - 属性配置结构体
            
            if nargin < 1 || isempty(configPath)
                configPath = fullfile(fileparts(mfilename('fullpath')), ...
                    '../../utilities/requirements_management/requirement_management_config.yml');
            end
            
            try
                config = yamlread(configPath);
                
                if isfield(config, 'slreqxSettings') && isfield(config.slreqxSettings, 'filterConfig')
                    filterConfig = config.slreqxSettings.filterConfig;
                else
                    error('配置文件中未找到 slreqxSettings.filterConfig');
                end
                
                if isfield(config, 'attributes')
                    attributeConfig = config.attributes;
                else
                    error('配置文件中未找到 attributes');
                end
                
            catch ME
                error('加载过滤器配置失败: %s', ME.message);
            end
        end
        
        function [filterPanel, filterControls] = createFilterPanel(parentGrid, row, reqType, filterConfig, attributeConfig)
            % 动态创建过滤器面板
            % 输入：
            %   parentGrid - 父网格布局
            %   row - 行号
            %   reqType - 需求类型('HLR'或'SRS')
            %   filterConfig - 过滤器配置
            %   attributeConfig - 属性配置
            % 输出：
            %   filterPanel - 过滤器面板对象
            %   filterControls - 过滤器控件结构体
            
            % 创建面板
            filterPanel = uipanel(parentGrid);
            filterPanel.Layout.Row = row;
            filterPanel.Layout.Column = 1;
            filterPanel.Title = sprintf('%s Filters', reqType);
            filterPanel.FontWeight = 'bold';
            filterPanel.BackgroundColor = [0.95 0.98 1];
            
            % 解析启用的过滤器
            [enabledFilters, filterCount] = RequirementFilterManager.parseEnabledFilters(filterConfig);
            
            if filterCount == 0
                % 没有启用的过滤器
                filterControls = struct();
                return;
            end
            
            % 创建网格布局：2行N列（标签行|控件行）
            filterGrid = uigridlayout(filterPanel, [2, filterCount + 1]);  % +1 for reset button
            filterGrid.RowHeight = {'fit', 'fit'};
            
            % 动态设置列宽
            colWidths = cell(1, filterCount + 1);
            for i = 1:filterCount
                colWidths{i} = 120;  % 过滤器列宽
            end
            colWidths{end} = 80;  % 重置按钮列宽
            filterGrid.ColumnWidth = colWidths;
            
            filterGrid.Padding = [10, 10, 10, 10];
            filterGrid.ColumnSpacing = 10;
            filterGrid.RowSpacing = 5;
            
            % 创建过滤器控件
            filterControls = struct();
            colIdx = 1;
            
            for i = 1:length(enabledFilters)
                filter = enabledFilters{i};
                
                % 创建标签
                label = uilabel(filterGrid);
                label.Layout.Row = 1;
                label.Layout.Column = colIdx;
                label.Text = filter.displayName;
                label.FontWeight = 'bold';
                label.HorizontalAlignment = 'center';
                
                % 创建控件
                if strcmp(filter.filterType, 'dropdown')
                    % 下拉框过滤器
                    dropdown = uidropdown(filterGrid);
                    dropdown.Layout.Row = 2;
                    dropdown.Layout.Column = colIdx;
                    
                    % 从attributes获取选项
                    options = RequirementFilterManager.getFilterOptions(filter.property, attributeConfig);
                    dropdown.Items = ['全部', options];  % 添加"全部"选项
                    dropdown.Value = '全部';
                    
                    % 保存控件引用
                    filterControls.(filter.key) = dropdown;
                    
                elseif strcmp(filter.filterType, 'search')
                    % 搜索框过滤器
                    searchField = uieditfield(filterGrid, 'text');
                    searchField.Layout.Row = 2;
                    searchField.Layout.Column = colIdx;
                    
                    if isfield(filter, 'placeholder')
                        searchField.Placeholder = filter.placeholder;
                    else
                        searchField.Placeholder = '搜索...';
                    end
                    
                    % 保存控件引用
                    filterControls.(filter.key) = searchField;
                end
                
                colIdx = colIdx + 1;
            end
            
            % 创建重置按钮
            resetLabel = uilabel(filterGrid);
            resetLabel.Layout.Row = 1;
            resetLabel.Layout.Column = colIdx;
            resetLabel.Text = '重置';
            resetLabel.FontWeight = 'bold';
            resetLabel.HorizontalAlignment = 'center';
            
            resetButton = uibutton(filterGrid, 'push');
            resetButton.Layout.Row = 2;
            resetButton.Layout.Column = colIdx;
            resetButton.Text = '重置';
            resetButton.BackgroundColor = [0.9 0.9 0.9];
            
            filterControls.resetButton = resetButton;
        end
        
        function [enabledFilters, filterCount] = parseEnabledFilters(filterConfig)
            % 解析启用的过滤器
            % 输入：filterConfig - 过滤器配置
            % 输出：
            %   enabledFilters - 启用的过滤器cell array
            %   filterCount - 启用的过滤器数量
            
            enabledFilters = {};
            filterNames = fieldnames(filterConfig);
            
            for i = 1:length(filterNames)
                filterName = filterNames{i};
                filter = filterConfig.(filterName);
                
                % 检查是否启用
                if isfield(filter, 'enabled') && filter.enabled
                    % 添加key字段（用于控件引用）
                    filter.key = filterName;
                    enabledFilters{end+1} = filter; %#ok<AGROW>
                end
            end
            
            % 按order字段排序
            if ~isempty(enabledFilters)
                orders = cellfun(@(f) f.order, enabledFilters);
                [~, sortIdx] = sort(orders);
                enabledFilters = enabledFilters(sortIdx);
            end
            
            filterCount = length(enabledFilters);
        end
        
        function options = getFilterOptions(property, attributeConfig)
            % 从attributes配置获取过滤器选项
            % 输入：
            %   property - 属性名称
            %   attributeConfig - 属性配置
            % 输出：options - 选项cell array
            
            options = {};
            
            % 特殊处理：search类型不需要选项
            if strcmp(property, 'search')
                return;
            end
            
            % 在attributes中查找对应的属性
            attrNames = fieldnames(attributeConfig);
            for i = 1:length(attrNames)
                attrName = attrNames{i};
                attr = attributeConfig.(attrName);
                
                % 通过targetProperty匹配
                if isfield(attr, 'targetProperty') && strcmp(attr.targetProperty, property)
                    % 检查是否为Combobox类型
                    if isfield(attr, 'type') && strcmp(attr.type, 'Combobox')
                        if isfield(attr, 'comboboxOptions')
                            options = attr.comboboxOptions;
                            return;
                        else
                            error('属性"%s"的type为Combobox，但未定义comboboxOptions', property);
                        end
                    else
                        error('属性"%s"不是Combobox类型，无法用作dropdown过滤器', property);
                    end
                end
            end
            
            % 如果未找到，报错
            if isempty(options)
                error('在attributes配置中未找到property为"%s"的Combobox属性', property);
            end
        end
        
        function filters = buildFilterStruct(filterControls, enabledFilters)
            % 从过滤器控件构建过滤器结构体
            % 输入：
            %   filterControls - 过滤器控件结构体
            %   enabledFilters - 启用的过滤器配置
            % 输出：filters - 过滤器结构体（用于数据过滤）
            
            filters = struct();
            
            for i = 1:length(enabledFilters)
                filter = enabledFilters{i};
                
                if isfield(filterControls, filter.key)
                    control = filterControls.(filter.key);
                    
                    if strcmp(filter.filterType, 'dropdown')
                        % 下拉框过滤器
                        filters.(filter.property) = control.Value;
                    elseif strcmp(filter.filterType, 'search')
                        % 搜索框过滤器
                        filters.searchText = control.Value;
                    end
                end
            end
        end
        
        function resetFilters(filterControls, enabledFilters)
            % 重置所有过滤器
            % 输入：
            %   filterControls - 过滤器控件结构体
            %   enabledFilters - 启用的过滤器配置
            
            for i = 1:length(enabledFilters)
                filter = enabledFilters{i};
                
                if isfield(filterControls, filter.key)
                    control = filterControls.(filter.key);
                    
                    if strcmp(filter.filterType, 'dropdown')
                        control.Value = '全部';
                    elseif strcmp(filter.filterType, 'search')
                        control.Value = '';
                    end
                end
            end
        end
        
    end
end

